#include "SDL.h"
#include "SDL_syswm.h"
#include "core\SkCanvas.h"
#include "core\SkSurface.h"
#include "win\WindowContextFactory_win.h"
#include "WindowContext.h"
#include <wingdi.h>
#include <signal.h>

#include "benchmark/benchmark.h"

#include <iostream>
using namespace std;
#define TEST 2   //1-4

HWND hwnd;
SDL_Window* win;
SDL_Renderer *renderer;
int w, h;
int line=10000;
bool loop = true;

void skia_paint(benchmark::State& state)
{
    //////////////////////////////////////////////////////////skia
    sk_app::DisplayParams param;
    std::unique_ptr<sk_app::WindowContext> wc = sk_app::window_context_factory::MakeRasterForWin(hwnd,param);
    // SkOSWindow* swin = SkOSWindow::GetOSWindowForHWND(hwnd);
    SkCanvas* canvas = wc->getBackbufferSurface()->getCanvas();

    SkPaint paint;//画笔等属性
    paint.setColor(SkColor(0xffff0000));
    paint.setStrokeWidth(SkScalar(1));

    canvas->clear(SK_ColorWHITE);
    for (auto _ : state) 
        for(int i=0;i<state.range(0);i++){
            canvas->drawLine(i%w,rand()%h,i%w,rand()%h,paint);
        }
    canvas->flush();
    wc->swapBuffers();
}
void skia_gpu_paint(benchmark::State& state)
{
    //skia gpu
    sk_app::DisplayParams param;
    std::unique_ptr<sk_app::WindowContext> wc;
    wc = sk_app::window_context_factory::MakeGLForWin(hwnd,param);//NewVulkanForWin，NewGLForWin
    SkCanvas* canvas = wc->getBackbufferSurface()->getCanvas();

    SkPaint paint;//画笔等属性
    paint.setColor(SkColor(0xffff0000));
    paint.setStrokeWidth(SkScalar(1));

    canvas->clear(SK_ColorWHITE);
    for (auto _ : state) 
        for(int i=0;i<state.range(0);i++){
            canvas->drawLine(i%w,rand()%h,i%w,rand()%h,paint);
        }
    canvas->flush();
    wc->swapBuffers();
}
void sdl_paint(benchmark::State& state)
{
    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    SDL_RenderClear(renderer);
    SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
    for (auto _ : state) 
        for(int i=0;i<state.range(0);i++){
            SDL_RenderDrawLine(renderer,i%w,rand()%h,i%w,rand()%h);
        }
    SDL_RenderPresent(renderer);// 交换缓冲区
}
void gdi_paint(benchmark::State& state)
{
    //////////////////////////////////////////////////////////gdi
    HDC hdc=GetDC(hwnd);
    HDC hMem = CreateCompatibleDC(hdc);
    HBITMAP hBM = CreateCompatibleBitmap(hdc,w,h);
    HPEN hPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
    SelectObject(hMem,hBM);
    SelectObject(hMem,hPen);
    FloodFill(hMem,0,0,RGB(255,255,255));
    for (auto _ : state) 
        for(int i=0;i<state.range(0);i++){
            LineTo(hMem,i%w,rand()%h);
            LineTo(hMem,i%w,rand()%h);
        }
    BitBlt(hdc,0,0,w,h,hMem,0,0,SRCCOPY);
    ReleaseDC(NULL,hdc);
}

BENCHMARK(skia_paint)->Arg(1000)->Arg(10000)->Arg(100000);
BENCHMARK(sdl_paint)->Arg(1000)->Arg(10000)->Arg(100000);
BENCHMARK(gdi_paint)->Arg(1000)->Arg(10000)->Arg(100000);
BENCHMARK(skia_gpu_paint)->Arg(1000)->Arg(10000)->Arg(100000);

int main(int argc, char** argv)
{
    w = 800, h = 600;
    SDL_Init(SDL_INIT_EVERYTHING);
    signal(SIGABRT, [](int){loop=false;});
    win = SDL_CreateWindow("skia",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,w,h,SDL_WINDOW_RESIZABLE);    
    //renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
    renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_SOFTWARE);

    SDL_SysWMinfo wmInfo;
    SDL_VERSION(&wmInfo.version);
    SDL_GetWindowWMInfo(win, &wmInfo);
    hwnd = wmInfo.info.win.window;
    SDL_GetWindowSize(win,&w,&h);

    benchmark::Initialize(&argc, argv);
    benchmark::RunSpecifiedBenchmarks();
    benchmark::Shutdown();

    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(win);
    SDL_Quit();
    
    return 0;
}